from django.db import models

# Create your models here.
class BaseModel(models.Model):
    updatetime = models.DateTimeField('更新时间', auto_now=True, null=True)
    createtime = models.DateTimeField('创建时间', auto_now_add=True, null=True)
    creater = models.ForeignKey('auth.user', verbose_name='创建人',on_delete=models.CASCADE)

    class Meta:
        abstract = True


class Project(BaseModel):
    name = models.CharField(max_length=100)
    version = models.CharField(max_length=100,null=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = '测试项目'

class Api(BaseModel):
    name = models.CharField('名称',max_length=100)
    project = models.ForeignKey(Project,verbose_name='所属项目',on_delete=models.SET_NULL,null=True)
    group = models.ForeignKey('ApiGroup',verbose_name='所属分组',on_delete=models.SET_NULL,null=True)
    header = models.ManyToManyField('Header',verbose_name='请求头',related_name='header_apis',blank=True)
    method = models.CharField('请求方法',choices=[('GET', "GET"),('POST', "POST"),('DELETE', "DELETE")],max_length=10)
    description = models.TextField('描述',max_length=1000,null=True,blank=True)
    url = models.CharField(max_length=100)
    # jsondatas = models.ManyToManyField('JsonKey',verbose_name='请求字段',through='ApiJson')

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = '接口管理'

class ApiGroup(BaseModel):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = '接口分组'

class Header(models.Model):
    key = models.CharField(max_length=100)
    value = models.CharField(max_length=1000)

    def __str__(self):
        return self.key + '-' + self.value

    class Meta:
        verbose_name_plural = '请求头'

class TestStep(BaseModel):
    name = models.CharField('名称', max_length=100)
    # project = models.ForeignKey(Project, verbose_name='所属项目', on_delete=models.SET_NULL, null=True)
    api = models.ForeignKey('Api', on_delete=models.CASCADE)
    body = models.JSONField('请求体',default=dict,blank=True)
    mode = models.CharField('参数类型',choices=[('with_params', "with_params"),('with_json', "with_json"),('with_data', "with_data"),('upload', "upload")],max_length=20,default='with_json')
    setup_hooks = models.ManyToManyField('Hook', verbose_name='前置方法', related_name='setup_hooks_teststep',blank=True)
    teardown_hooks = models.ManyToManyField('Hook', verbose_name='后置方法', related_name='teardown_hooks_teststep',blank=True)
    allow_redirects = models.BooleanField('是否允许跳转',default=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = '测试步骤'

class Variables_through(models.Model):
    testcase = models.ForeignKey('TestCase',on_delete=models.CASCADE,null=True,blank=True)
    teststep = models.ForeignKey('TestStep',on_delete=models.CASCADE,null=True,blank=True)
    variablekey = models.ForeignKey('Variablekey', on_delete=models.CASCADE)
    variableval = models.CharField('Variableval', max_length=1000,null=True,blank=True)

    def __str__(self):
        return self.variablekey.value +':' +  self.variableval

    class Meta:
        verbose_name_plural = '变量关系'

class Variablekey(models.Model):
    value = models.CharField(max_length=100)

    def __str__(self):
        return self.value

class Cookies_through(models.Model):
    teststep = models.ForeignKey('TestStep',on_delete=models.CASCADE,null=True,blank=True)
    cookieskey = models.ForeignKey('Cookieskey', on_delete=models.CASCADE)
    cookiesval = models.CharField('Cookiesval', max_length=1000,null=True,blank=True)

    def __str__(self):
        return self.cookieskey.value +':' +  self.cookiesval

    class Meta:
        verbose_name_plural = '变量关系'

class Cookieskey(models.Model):
    value = models.CharField(max_length=100)

    def __str__(self):
        return self.value


class Extract_through(models.Model):
    teststep = models.ForeignKey('TestStep',on_delete=models.CASCADE)
    extractkey = models.ForeignKey('Extractkey', on_delete=models.CASCADE)
    extractval = models.ForeignKey('Extractval', on_delete=models.CASCADE)

    def __str__(self):
        return self.extractkey.value +':' +  self.extractval.value

    class Meta:
        verbose_name_plural = '输出变量关系'

class Extractkey(models.Model):
    value = models.CharField(max_length=100)

    def __str__(self):
        return self.value

class Extractval(models.Model):
    value = models.CharField(max_length=100)

    def __str__(self):
        return self.value

class Validates_through(models.Model):
    teststep = models.ForeignKey('TestStep', on_delete=models.CASCADE)
    validatekey = models.ForeignKey('Validatekey', verbose_name='断言路径', on_delete=models.SET_NULL, null=True,
                                 help_text='填写jmespath路径')
    validateval = models.ForeignKey('Validateval', verbose_name='预期值', on_delete=models.SET_NULL, null=True)
    mode = models.CharField('模式', choices=[('assert_equal', "完全匹配"), ('assert_not_equal', "不匹配"),
                                           ('assert_string_equals', "字符匹配（不校验类型）"), ('assert_startswith', "字符开头匹配"),
                                           ('assert_endswith', "字符结尾匹配"), ('assert_contained_by', "预期值包含结果"),
                                           ('assert_type_match', "类型匹配"), ('assert_length_equal', "长度匹配"),
                                           ('assert_length_greater_than', "长度大于预期值"),
                                           ('assert_length_less_than', "长度小于预期值"),
                                           ('assert_length_greater_or_equals', "长度大于等于预期值"),
                                           ('assert_length_less_or_equals', "长度小于等于预期值"),
                                           ('assert_contains', "结果包含预期值"), ('assert_regex_match', "正则表达式匹配")],
                            max_length=100, default='assert_equal')

    def __str__(self):
        return self.validatekey.value + '-' + self.validateval.value

    class Meta:
        verbose_name_plural = '断言关系参数'

class Validatekey(models.Model):
    value = models.CharField(max_length=100)

    def __str__(self):
        return self.value

class Validateval(models.Model):
    value = models.CharField(max_length=100)
    type = models.CharField('类型', choices=[('str', "string"), ('int', "int"), ('True', "True"), ('False', "False")], max_length=10,default='str')

    def __str__(self):
        return self.value

class Hook(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class BASEURL(models.Model):
    name = models.CharField('环境', max_length=100)
    url = models.CharField('url', max_length=100)
    project = models.ForeignKey(Project, on_delete=models.SET_NULL, null=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = '测试环境'

class TestCase(BaseModel):
    name = models.CharField('名称', max_length=100)
    # project = models.ForeignKey(Project, verbose_name='所属项目', on_delete=models.SET_NULL, null=True)
    paramfile = models.FileField(upload_to='paramfile',verbose_name='参数化文件',null=True,blank=True)
    teststeps = models.ManyToManyField('TestStep',verbose_name='测试步骤',through='Teststeps_through')
    baseurl = models.ForeignKey(BASEURL,on_delete=models.SET_NULL,verbose_name='测试环境',null=True)
    export = models.ManyToManyField(Extract_through,verbose_name='输出参数',blank=True)
    relation = models.IntegerField('优先级')

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = '测试用例'

class Teststeps_through(models.Model):
    testcase = models.ForeignKey('TestCase', on_delete=models.CASCADE)
    teststep = models.ForeignKey('TestStep', on_delete=models.CASCADE)
    runno = models.IntegerField('顺序号')

    def __str__(self):
        return self.testcase.name

    class Meta:
        verbose_name_plural = '顺序运行用例'

class Parameters_through(models.Model):
    testcase = models.ForeignKey('TestCase',on_delete=models.CASCADE)
    paramkey = models.ForeignKey('Paramkey', on_delete=models.CASCADE)
    paramval = models.ForeignKey('Paramval', on_delete=models.CASCADE)

    def __str__(self):
        return self.paramkey.value

    class Meta:
        verbose_name_plural = '参数化'

class Paramkey(models.Model):
    value = models.CharField(max_length=100)

    def __str__(self):
        return self.value

class Paramval(models.Model):
    value = models.CharField(max_length=100)

    def __str__(self):
        return self.value

class TestSuite(BaseModel):
    name = models.CharField('名称', max_length=100)
    # project = models.ForeignKey(Project, verbose_name='所属项目', on_delete=models.SET_NULL, null=True)
    testcases = models.ManyToManyField('TestCase', verbose_name='测试用例集',blank=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = '测试套件'

class TESTREPORT(models.Model):
    reportname = models.CharField('名称', max_length=100)
    # project = models.ForeignKey(Project, verbose_name='所属项目', on_delete=models.SET_NULL, null=True)
    result = models.CharField('运行结果', choices=[('Y', "成功"), ('N', "失败")], max_length=10)
    reportfile = models.FileField(upload_to='testreport', verbose_name='报告文件',null=True)

    def __str__(self):
        return self.reportname

    class Meta:
        verbose_name_plural = '测试报告'